# A part of NonVisual Desktop Access (NVDA)
# Copyright (C) 2025 NV Access Limited
# This file may be used under the terms of the GNU General Public License, version 2 or later, as modified by the NVDA license.
# For full terms and any additional permissions, see the NVDA license file: https://github.com/nvaccess/nvda/blob/master/copying.txt

"""Functions exported by user32.dll, and supporting data structures and enumerations."""

from ctypes import (
	Structure,
	WINFUNCTYPE,
	Union,
	c_int,
	c_size_t,
	c_uint,
	c_long,
	c_longlong,
	c_void_p,
	sizeof,
	windll,
	POINTER,
)
from ctypes.wintypes import (
	BOOL,
	COLORREF,
	DWORD,
	BYTE,
	HDESK,
	HKL,
	HMODULE,
	HRGN,
	LONG,
	LPDWORD,
	LPPOINT,
	LPRECT,
	PBYTE,
	PHANDLE,
	PMSG,
	POINT,
	PRECT,
	RECT,
	HANDLE,
	HHOOK,
	HINSTANCE,
	HMENU,
	HICON,
	HBRUSH,
	HDC,
	HWND,
	LPARAM,
	LPWSTR,
	LPCWSTR,
	LPMSG,
	SHORT,
	UINT,
	WCHAR,
	WORD,
	WPARAM,
	ATOM,
)
from enum import IntEnum, IntFlag

UINT_PTR = c_size_t
ULONG_PTR = c_size_t
DWORD_PTR = c_size_t
PDWORD_PTR = POINTER(DWORD_PTR)


class PAINTSTRUCT(Structure):
	_fields_ = [
		("hdc", HDC),
		("fErase", BOOL),
		("rcPaint", RECT),
		("fRestore", BOOL),
		("fIncUpdate", BOOL),
		("rgbReserved", BYTE * 32),
	]


# LRESULT is defined as LONG_PTR (signed type)
if sizeof(c_long) == sizeof(c_void_p):
	LRESULT = c_long
elif sizeof(c_longlong) == sizeof(c_void_p):
	LRESULT = c_longlong
else:
	raise RuntimeError("Unsupported platform")


HCURSOR = HANDLE

WNDPROC = WINFUNCTYPE(LRESULT, HWND, c_uint, WPARAM, LPARAM)


class WNDCLASSEXW(Structure):
	_fields_ = [
		("cbSize", c_uint),  # noqa: F405
		("style", c_uint),  # noqa: F405
		("lpfnWndProc", WNDPROC),
		("cbClsExtra", c_int),
		("cbWndExtra", c_int),
		("hInstance", HINSTANCE),  # noqa: F405
		("hIcon", HICON),  # noqa: F405
		("HCURSOR", HCURSOR),
		("hbrBackground", HBRUSH),  # noqa: F405
		("lpszMenuName", LPWSTR),  # noqa: F405
		("lpszClassName", LPWSTR),  # noqa: F405
		("hIconSm", HICON),  # noqa: F405
	]


dll = windll.user32

CallNextHookEx = WINFUNCTYPE(None)(("CallNextHookEx", dll))
"""
.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-callnexthookex
"""
CallNextHookEx.argtypes = (
	HHOOK,  # hook
	c_int,  # code
	WPARAM,
	LPARAM,
)
CallNextHookEx.restype = LRESULT

GetMessage = WINFUNCTYPE(None)(("GetMessageW", dll))
"""
Retrieves a message from the calling thread's message queue, dispatching incoming sent messages until a posted message is available for retrieval.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmessagew
"""
GetMessage.argtypes = (
	LPMSG,  # lpMsg
	HWND,  # hWnd
	UINT,  # wMsgFilterMin
	UINT,  # wMsgFilterMax
)
GetMessage.restype = BOOL

HOOKPROC = WINFUNCTYPE(LRESULT, c_int, WPARAM, LPARAM)  # noqa: F405

SetWindowsHookEx = WINFUNCTYPE(None)(("SetWindowsHookExW", dll))
SetWindowsHookEx.argtypes = (
	c_int,  # idHook
	HOOKPROC,  # lpfn
	HINSTANCE,  # hMod
	DWORD,  # dwThreadId
)
SetWindowsHookEx.restype = HHOOK

DefWindowProc = WINFUNCTYPE(None)(("DefWindowProcW", dll))
"""
Calls the default window procedure to provide default processing for any window messages that an application does not process.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-defwindowprocw
"""
DefWindowProc.argtypes = (
	HWND,
	UINT,  # msg
	WPARAM,
	LPARAM,
)
DefWindowProc.restype = LRESULT

HWINEVENTHOOK = HANDLE
"""
Used to declare a window event hook function.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/winauto/hwineventhook
"""

WINEVENTPROC = WINFUNCTYPE(None, HWINEVENTHOOK, DWORD, HWND, LONG, LONG, DWORD, DWORD)
"""
An application-defined callback that the system calls in response to events generated by an accessible object.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nc-winuser-wineventproc
"""

SetWinEventHook = WINFUNCTYPE(None)(("SetWinEventHook", dll))
"""
Sets an event hook function for a range of events.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwineventhook
"""
SetWinEventHook.restype = HWINEVENTHOOK
SetWinEventHook.argtypes = (
	DWORD,  # eventMin: Specifies the lowest event value that is handled by the hook function
	DWORD,  # eventMax: Specifies the highest event value that is handled by the hook function
	HMODULE,  # hmodWinEventProc: Handle to the DLL that contains the hook function, if the WINEVENT_INCONTEXT flag is specified, otherwise NULL
	WINEVENTPROC,  # pfnWinEventProc: Pointer to the event hook function
	DWORD,  # idProcess: The ID of the process from which the hook function receives events
	DWORD,  # idThread: The ID of the thread from which the hook function receives events
	DWORD,  # dwFlags: Specifies the location of the hook function and of the events to be skipped
)

UnhookWinEvent = WINFUNCTYPE(None)(("UnhookWinEvent", dll))
"""
Removes an event hook function created by a previous call to SetWinEventHook.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-unhookwinevent
"""
UnhookWinEvent.restype = BOOL
UnhookWinEvent.argtypes = (
	HWINEVENTHOOK,  # hWinEventHook: Handle to the event to unhook
)

NotifyWinEvent = WINFUNCTYPE(None)(("NotifyWinEvent", dll))
"""
Signals the system that a predefined event occurred.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-notifywinevent
"""
NotifyWinEvent.restype = None
NotifyWinEvent.argtypes = (
	DWORD,  # event: The event that occurred
	HWND,  # hwnd: Handle to the window that contains the object that generated the event
	LONG,  # idObject: The object that generated the event
	LONG,  # idChild: Whether the event was generated by an object or one of its children
)

CreateWindowEx = WINFUNCTYPE(None)(("CreateWindowExW", dll))
"""
Creates an overlapped, pop-up, or child window with an extended window style.
.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw
"""
CreateWindowEx.argtypes = (
	DWORD,  # dwExStyle
	LPCWSTR,  # lpClassName
	LPCWSTR,  # lpWindowName
	DWORD,  # dwStyle
	c_int,  # x
	c_int,  # y
	c_int,  # nWidth
	c_int,  # nHeight
	HWND,  # hWndParent
	HMENU,  # hMenu
	HINSTANCE,  # hInstance
	c_void_p,  # lpParam
)
CreateWindowEx.restype = HWND

RegisterClassEx = WINFUNCTYPE(None)(("RegisterClassExW", dll))
"""
Registers a window class for subsequent use in calls to the CreateWindow or CreateWindowEx function.
.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw
"""
RegisterClassEx.argtypes = (
	POINTER(WNDCLASSEXW),  # lpWndClass
)
RegisterClassEx.restype = ATOM

UnregisterClass = WINFUNCTYPE(None)(("UnregisterClassW", dll))
"""
Unregisters a window class, freeing the memory used by the class and removing it from the system.
.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-unregisterclassw
"""
UnregisterClass.argtypes = (
	LPCWSTR,  # lpClassName
	HINSTANCE,  # hInstance
)
UnregisterClass.restype = BOOL

BeginPaint = WINFUNCTYPE(None)(("BeginPaint", dll))
"""
Begins painting in the specified window by filling a PAINTSTRUCT structure with information about the painting.
.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-beginpaint
"""
BeginPaint.argtypes = (
	HWND,  # hWnd
	POINTER(PAINTSTRUCT),  # lpPaint
)
BeginPaint.restype = HDC

EndPaint = WINFUNCTYPE(None)(("EndPaint", dll))
"""
Ends painting in the specified window by releasing the device context (DC) and invalidating the PAINTSTRUCT structure.
.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-endpaint
"""
EndPaint.argtypes = (
	HWND,  # hWnd
	POINTER(PAINTSTRUCT),  # lpPaint
)
EndPaint.restype = BOOL

OpenClipboard = WINFUNCTYPE(None)(("OpenClipboard", dll))
"""
Opens the clipboard for examination and prevents other applications from modifying the clipboard content until the clipboard is closed.
.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-openclipboard
"""
OpenClipboard.argtypes = (
	HWND,  # hWndNewOwner
)
OpenClipboard.restype = BOOL

CloseClipboard = WINFUNCTYPE(None)(("CloseClipboard", dll))
"""
Closes the clipboard and releases ownership of the clipboard to other applications.
.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-closeclipboard
"""
CloseClipboard.argtypes = ()
CloseClipboard.restype = BOOL

GetClipboardData = WINFUNCTYPE(None)(("GetClipboardData", dll))
"""
Retrieves data from the clipboard in a specified format.
.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getclipboarddata
"""
GetClipboardData.argtypes = (
	UINT,  # uFormat
)
GetClipboardData.restype = HANDLE

SetClipboardData = WINFUNCTYPE(None)(("SetClipboardData", dll))
"""
Places data on the clipboard in a specified format.
.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setclipboarddata
"""
SetClipboardData.argtypes = (
	UINT,  # uFormat
	HANDLE,  # hMem
)
SetClipboardData.restype = HANDLE

WNDENUMPROC = WINFUNCTYPE(BOOL, HWND, LPARAM)
"""
An application-defined callback function used with the EnumWindows or EnumDesktopWindows function.
It receives top-level window handles.
"""

EnumWindows = WINFUNCTYPE(None)(("EnumWindows", dll))
"""
Enumerates all top-level windows on the screen by passing the handle to each window,
in turn, to an application-defined callback function.
EnumWindows continues until the last top-level window is enumerated or the callback function returns FALSE.
.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enumwindows
"""
EnumWindows.argtypes = (
	WNDENUMPROC,  # lpEnumFunc
	LPARAM,  # lParam
)
EnumWindows.restype = BOOL

GetSystemMetrics = WINFUNCTYPE(None)(("GetSystemMetrics", dll))
"""
Retrieves the specified system metric or system configuration setting.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetrics
"""
GetSystemMetrics.restype = c_int
GetSystemMetrics.argtypes = (
	c_int,  # nIndex: The system metric or configuration setting to be retrieved
)

ChangeWindowMessageFilter = WINFUNCTYPE(None)(("ChangeWindowMessageFilter", dll))
"""
Adds or removes a message from the User Interface Privilege Isolation (UIPI) message filter.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-changewindowmessagefilter
"""
ChangeWindowMessageFilter.restype = BOOL
ChangeWindowMessageFilter.argtypes = (
	UINT,  # message: The message to add to or remove from the filter
	DWORD,  # dwFlag: The action to be performed
)

GetKeyState = WINFUNCTYPE(None)(("GetKeyState", dll))
"""
Retrieves the status (up, down, or toggled) of the specified virtual key.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getkeystate
"""
GetKeyState.restype = SHORT
GetKeyState.argtypes = (
	c_int,  # nVirtKey: A virtual key
)

SystemParametersInfo = WINFUNCTYPE(None)(("SystemParametersInfoW", dll))
"""
Retrieves or sets the value of one of the system-wide parameters.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-systemparametersinfow
"""
SystemParametersInfo.restype = BOOL
SystemParametersInfo.argtypes = (
	UINT,  # uiAction: The system-wide parameter to be retrieved or set
	UINT,  # uiParam: A parameter whose usage and format depends on the system parameter being queried or set
	c_void_p,  # pvParam: A parameter whose usage and format depends on the system parameter being queried or set
	UINT,  # fWinIni: If setting a system parameter, Whether to update the user profile, and if so, whether to  broadcast the change
)

WaitMessage = WINFUNCTYPE(None)(("WaitMessage", dll))
"""
Blocks thread execution until the thread needs to process a new message.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-waitmessage
"""
WaitMessage.restype = BOOL
WaitMessage.argtypes = ()

TranslateMessage = WINFUNCTYPE(None)(("TranslateMessage", dll))
"""
Translates virtual-key messages into character messages.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-translatemessage
"""
TranslateMessage.restype = BOOL
TranslateMessage.argtypes = (
	PMSG,  # lpMsg: A message retrieved from the calling thread's message queue
)

DispatchMessage = WINFUNCTYPE(None)(("DispatchMessageW", dll))
"""
Dispatches a message to a window procedure.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-dispatchmessagew
"""
DispatchMessage.restype = LRESULT
DispatchMessage.argtypes = (
	PMSG,  # lpMsg
)

PeekMessage = WINFUNCTYPE(None)(("PeekMessageW", dll))
"""
Dispatches incoming nonqueued messages, checks the thread message queue for a posted message, and retrieves the message (if any exist).

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-peekmessagew
"""
PeekMessage.restype = BOOL
PeekMessage.argtypes = (
	LPMSG,  # lpMsg: Pointer to an MSG structure that receives message information
	HWND,  # hWnd: Handle to the window whose messages are to be retrieved
	UINT,  # wMsgFilterMin: The value of the first message in the range of messages to be examined
	UINT,  # wMsgFilterMax: The value of the last message in the range of messages to be examined
	UINT,  # wRemoveMsg: Specifies how messages are to be handled
)

SendMessage = WINFUNCTYPE(None)(("SendMessageW", dll))
"""
Sends the specified message to a window or windows and does not return until the message has been processed.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendmessagew
"""
SendMessage.restype = LRESULT
SendMessage.argtypes = (
	HWND,  # hWnd: Handle to the window whose window procedure will receive the message
	UINT,  # Msg: The message to be sent
	WPARAM,  # wParam: Additional message-specific information
	LPARAM,  # lParam: Additional message-specific information
)

PostMessage = WINFUNCTYPE(None)(("PostMessageW", dll))
"""
Places a message in the message queue associated with the thread that created the specified window and returns without waiting for the thread to process the message.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-postmessagew
"""
PostMessage.restype = BOOL
PostMessage.argtypes = (
	HWND,  # hWnd: Handle to the window whose window procedure is to receive the message
	UINT,  # Msg: The message to be posted
	WPARAM,  # wParam: Additional message-specific information
	LPARAM,  # lParam: Additional message-specific information
)

GetAsyncKeyState = WINFUNCTYPE(None)(("GetAsyncKeyState", dll))
"""
Determines whether a key is up or down at the time the function is called.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getasynckeystate
"""
GetAsyncKeyState.restype = SHORT
GetAsyncKeyState.argtypes = (
	c_int,  # vKey: The virtual-key code
)

IsWindow = WINFUNCTYPE(None)(("IsWindow", dll))
"""
Determines whether the specified window handle identifies an existing window.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-iswindow
"""
IsWindow.restype = BOOL
IsWindow.argtypes = (
	HWND,  # hWnd: A handle to the window to be tested
)

IsChild = WINFUNCTYPE(None)(("IsChild", dll))
"""
Determines whether a window is a child or descendant window of a specified parent window.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-ischild
"""
IsChild.restype = BOOL
IsChild.argtypes = (
	HWND,  # hWndParent: Handle to the parent window
	HWND,  # hWnd: Handle to the window to be tested
)

GetForegroundWindow = WINFUNCTYPE(None)(("GetForegroundWindow", dll))
"""
Retrieves a handle to the foreground window (the window with which the user is currently working)

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getforegroundwindow
"""
GetForegroundWindow.restype = HWND
GetForegroundWindow.argtypes = ()

SetForegroundWindow = WINFUNCTYPE(None)(("SetForegroundWindow", dll))
"""
Brings the thread that created the specified window into the foreground and activates the window.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setforegroundwindow
"""
SetForegroundWindow.restype = BOOL
SetForegroundWindow.argtypes = (
	HWND,  # hWnd: Handle to the window that should be activated and brought to the foreground.
)

SetFocus = WINFUNCTYPE(None)(("SetFocus", dll))
"""
Sets the keyboard focus to the specified window.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setfocus
"""
SetFocus.restype = HWND
SetFocus.argtypes = (
	HWND,  # hWnd: Handle to the window that will receive the keyboard input
)

GetDesktopWindow = WINFUNCTYPE(None)(("GetDesktopWindow", dll))
"""
Retrieves a handle to the desktop window.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdesktopwindow
"""
GetDesktopWindow.restype = HWND
GetDesktopWindow.argtypes = ()

GetWindowLong = WINFUNCTYPE(None)(("GetWindowLongW", dll))
"""
Retrieves information about the specified window.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowlongw
"""
GetWindowLong.restype = LONG
GetWindowLong.argtypes = (
	HWND,  # hWnd: Handle to the window and, indirectly, the class to which the window belongs
	c_int,  # nIndex: Zero-based offset to the value to be retrieved
)

TIMERPROC = WINFUNCTYPE(None, HWND, UINT, UINT_PTR, DWORD)
"""
An application-defined callback function that processes WM_TIMER messages.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nc-winuser-timerproc
"""

SetTimer = WINFUNCTYPE(None)(("SetTimer", dll))
"""
Creates a timer with the specified time-out value.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-settimer
"""
SetTimer.restype = UINT_PTR
SetTimer.argtypes = (
	HWND,  # hWnd: handle to the window to be associated with the timer
	UINT_PTR,  # nIDEvent: A nonzero timer identifier
	UINT,  # uElapse: The time-out value, in milliseconds
	TIMERPROC,  # lpTimerFunc: Pointer to the function to be notified when the time-out value elapses
)

KillTimer = WINFUNCTYPE(None)(("KillTimer", dll))
"""
Destroys the specified timer.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-killtimer
"""
KillTimer.restype = BOOL
KillTimer.argtypes = (
	HWND,  # hWnd: Handle to the window associated with the specified timer
	UINT_PTR,  # uIDEvent: The timer to be destroyed
)


class MOUSEINPUT(Structure):
	"""
	Contains information about a simulated mouse event.

	.. seealso::
		https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-mouseinput
	"""

	_fields_ = (
		("dx", LONG),
		("dy", LONG),
		("mouseData", DWORD),
		("dwFlags", DWORD),
		("time", DWORD),
		("dwExtraInfo", ULONG_PTR),
	)


class KEYEVENTF(IntFlag):
	"""Specifies various aspects of a keystroke in a ``KEYBDINPUT`` struct.

	.. seealso::
		https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-keybdinput
	"""

	EXTENDEDKEY = 0x0001
	"""If specified, the wScan scan code consists of a sequence of two bytes, where the first byte has a value of 0xE0."""

	KEYUP = 0x0002
	"""If specified, the key is being released. If not specified, the key is being pressed. """

	SCANCODE = 0x0008
	"""If specified, wScan identifies the key and wVk is ignored. """

	UNICODE = 0x0004
	"""If specified, the system synthesizes a VK_PACKET keystroke.

	.. warning::
		Must only be combined with :const:`KEYUP`.
	"""


class KEYBDINPUT(Structure):
	"""
	Contains information about a simulated keyboard event.

	.. seealso::
		https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-keybdinput
	"""

	_fields_ = (
		("wVk", WORD),
		("wScan", WORD),
		("dwFlags", DWORD),
		("time", DWORD),
		("dwExtraInfo", ULONG_PTR),
	)


class HARDWAREINPUT(Structure):
	"""
	Contains information about a simulated message generated by an input device other than a keyboard or mouse.

	.. seealso::
		https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-hardwareinput
	"""

	_fields_ = (
		("uMsg", DWORD),
		("wParamL", WORD),
		("wParamH", WORD),
	)


class _INPUT_I(Union):
	"""
	Type of `Input.DUMMYUNIONNAME`.
	"""

	_fields_ = (
		("mi", MOUSEINPUT),
		("ki", KEYBDINPUT),
		("hi", HARDWAREINPUT),
	)


class INPUT_TYPE(IntEnum):
	"""Values permissible as the ``type`` field in an ``INPUT`` struct.

	.. seealso::
		https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-input
	"""

	MOUSE = 0
	"""The event is a mouse event. Use the mi structure of the union."""

	KEYBOARD = 1
	"""The event is a keyboard event. Use the ki structure of the union."""

	HARDWARE = 2
	"""The event is a hardware event. Use the hi structure of the union."""


class INPUT(Structure):
	"""
	Used by SendInput to store information for synthesizing input events such as keystrokes, mouse movement, and mouse clicks.

	.. seealso::
		https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-input
	"""

	_fields_ = (
		("type", DWORD),
		("ii", _INPUT_I),
	)


LPINPUT = POINTER(INPUT)

SendInput = WINFUNCTYPE(None)(("SendInput", dll))
"""
Synthesizes keystrokes, mouse motions, and button clicks.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendinput
"""
SendInput.restype = UINT
SendInput.argtypes = (
	UINT,  # cInputs: The number of structures in the pInputs array
	LPINPUT,  # pInputs: Array of events to be inserted into the keyboard or mouse input stream
	c_int,  # cbSize: The size, in bytes, of an INPUT structure
)

keybd_event = WINFUNCTYPE(None)(("keybd_event", dll))
"""
Synthesizes a keystroke.

.. note::
	This function has been superseded. Use ``SendInput`` instead.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-keybd_event
"""
keybd_event.restype = None
keybd_event.argtypes = (
	BYTE,  # bVk: A virtual-key code
	BYTE,  # bScan: Hardware scan code for the key
	DWORD,  # dwFlags: Controls various aspects of function operation
	ULONG_PTR,  # dwExtraInfo: An additional value associated with the key stroke
)

mouse_event = WINFUNCTYPE(None)(("mouse_event", dll))
"""
Synthesizes mouse motion and button clicks.

.. note::
	This function has been superseded. Use `SendInput` instead.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-mouse_event
"""
mouse_event.restype = None
mouse_event.argtypes = (
	DWORD,  # dwFlags: Controls various aspects of mouse motion and button clicking
	DWORD,  # dx: The absolute position or amount of motion along the x-axis
	DWORD,  # dy: The absolute position or amount of motion along the y-axis
	DWORD,  # dwData: Specifics of the event
	ULONG_PTR,  # dwExtraInfo: An additional value associated with the mouse event
)

VkKeyScanEx = WINFUNCTYPE(None)(("VkKeyScanExW", dll))
"""
Translates a character to the corresponding virtual-key code and shift state.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-vkkeyscanexw
"""
VkKeyScanEx.restype = SHORT
VkKeyScanEx.argtypes = (
	WCHAR,  # ch: The character to be translated into a virtual-key code
	HKL,  # dwhkl: Input locale identifier used to translate the character
)

GetKeyNameText = WINFUNCTYPE(None)(("GetKeyNameTextW", dll))
"""
Retrieves a string that represents the name of a key.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-GetKeyNameTextW
"""
GetKeyNameText.restype = int
GetKeyNameText.argtypes = (
	LONG,  # lParam: The second parameter of the keyboard message (such as WM_KEYDOWN) to be processed
	LPWSTR,  # lpString: The buffer that will receive the key name
	c_int,  # cchSize: The maximum length, in characters, of the key name, including the terminating null character
)

GetKeyboardLayout = WINFUNCTYPE(None)(("GetKeyboardLayout", dll))
"""
Retrieves the active input locale identifier (formerly called the keyboard layout).

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-GetKeyboardLayout
"""
GetKeyboardLayout.restype = HKL
GetKeyboardLayout.argtypes = (
	DWORD,  # idThread: The identifier of the thread to query, or 0 for the current thread
)

GetPhysicalCursorPos = WINFUNCTYPE(None)(("GetPhysicalCursorPos", dll))
"""
Retrieves the position of the cursor in physical coordinates.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getphysicalcursorpos
"""
GetPhysicalCursorPos.restype = BOOL
GetPhysicalCursorPos.argtypes = (
	LPPOINT,  # lpPoint: The position of the cursor, in physical coordinates
)

SetPhysicalCursorPos = WINFUNCTYPE(None)(("SetPhysicalCursorPos", dll))
"""
Sets the position of the cursor in physical coordinates.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-SetPhysicalCursorPos
"""
SetPhysicalCursorPos.restype = BOOL
SetPhysicalCursorPos.argtypes = (
	c_int,  # X: The new x-coordinate of the cursor, in physical coordinates
	c_int,  # Y: The new y-coordinate of the cursor, in physical coordinates
)

GetWindowThreadProcessId = WINFUNCTYPE(None)(("GetWindowThreadProcessId", dll))
"""
Retrieves the identifier of the thread that created the specified window and, optionally, the identifier of the process that created the window.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowthreadprocessid
"""
GetWindowThreadProcessId.restype = DWORD
GetWindowThreadProcessId.argtypes = (
	HWND,  # hWnd: Handle to the window
	LPDWORD,  # lpdwProcessId: Optional pointer to a variable that receives the process identifier
)

GetClassName = WINFUNCTYPE(None)(("GetClassNameW", dll))
"""
Retrieves the name of the class to which the specified window belongs.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getclassnamew
"""
GetClassName.restype = c_int
GetClassName.argtypes = (
	HWND,  # hWnd: Handle to the window and, indirectly, the class to which the window belongs
	LPWSTR,  # lpClassName: The class name string
	c_int,  # nMaxCount: Length of the lpClassName buffer, in characters
)

GetAncestor = WINFUNCTYPE(None)(("GetAncestor", dll))
"""
Retrieves the handle to the ancestor of the specified window.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getancestor
"""
GetAncestor.restype = HWND
GetAncestor.argtypes = (
	HWND,  # hwnd: Handle to the window whose ancestor is to be retrieved
	UINT,  # gaFlags: The ancestor to be retrieved
)

GetCaretPos = WINFUNCTYPE(None)(("GetCaretPos", dll))
"""
Copies the caret's position to the specified POINT structure.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getcaretpos
"""
GetCaretPos.restype = BOOL
GetCaretPos.argtypes = (
	LPPOINT,  # lpPoint: pointer to the POINT structure that is to receive the client coordinates of the caret
)


GetTopWindow = WINFUNCTYPE(None)(("GetTopWindow", dll))
"""
retrieves a handle to the parent window's  top most child window  in the Z order.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-gettopwindow
"""
GetTopWindow.restype = HWND
GetTopWindow.argtypes = (
	HWND,  # hWnd: Handle to the parent window whose child windows are to be examined
)

InternalGetWindowText = WINFUNCTYPE(None)(("InternalGetWindowText", dll))
"""
Copies the text of the specified window's title bar (if it has one) into a buffer.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-internalgetwindowtext
"""
InternalGetWindowText.restype = c_int
InternalGetWindowText.argtypes = (
	HWND,  # hWnd : handle to the window or control containing the text
	LPWSTR,  # pString: The buffer that is to receive the text
	c_int,  # cchMaxCount: Maximum number of characters to be copied to the buffer, including the null character
)

GetWindow = WINFUNCTYPE(None)(("GetWindow", dll))
"""
Retrieves a handle to a window that has the specified relationship to the specified window.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindow
"""
GetWindow.restype = HWND
GetWindow.argtypes = (
	HWND,  # hWnd: Handle to a window
	UINT,  # uCmd: The relationship between the specified window and the window to be retrieved
)

IsWindowVisible = WINFUNCTYPE(None)(("IsWindowVisible", dll))
"""
Determines the visibility state of the specified window.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-iswindowvisible
"""
IsWindowVisible.restype = BOOL
IsWindowVisible.argtypes = (
	HWND,  # hWnd: Handle to the window to be tested
)

IsWindowEnabled = WINFUNCTYPE(None)(("IsWindowEnabled", dll))
"""
Determines whether the specified window is enabled for mouse and keyboard input.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-iswindowenabled
"""
IsWindowEnabled.restype = BOOL
IsWindowEnabled.argtypes = (
	HWND,  # hWnd: Handle to the window to be tested
)


class GUITHREADINFO(Structure):
	"""
	Contains information about a GUI thread.

	.. seealso::
		https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-guithreadinfo
	"""

	_fields_ = (
		("cbSize", DWORD),
		("flags", DWORD),
		("hwndActive", HWND),
		("hwndFocus", HWND),
		("hwndCapture", HWND),
		("hwndMenuOwner", HWND),
		("hwndMoveSize", HWND),
		("hwndCaret", HWND),
		("rcCaret", RECT),
	)


PGUITHREADINFO = POINTER(GUITHREADINFO)


GetGUIThreadInfo = WINFUNCTYPE(None)(("GetGUIThreadInfo", dll))
"""
Retrieves information about the active window or a specified GUI thread.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getguithreadinfo
"""
GetGUIThreadInfo.restype = BOOL
GetGUIThreadInfo.argtypes = (
	DWORD,  # idThread: The identifier of the thread for which information is to be retrieved
	PGUITHREADINFO,  # pgui: pointer to a GUITHREADINFO structure that receives information describing the thread
)

SetWindowLong = WINFUNCTYPE(None)(("SetWindowLongW", dll))
"""
Changes an attribute of the specified window.

.. note::
	This function has been superseded by the ``SetWindowLongPtr`` function.
	To write code that is compatible with both 32-bit and 64-bit versions of Windows,
	use the ``SetWindowLongPtr`` function.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowlongw
"""
SetWindowLong.restype = LONG
SetWindowLong.argtypes = (
	HWND,  # hWnd: Handle to the window and, indirectly, the class to which the window belongs.
	c_int,  # nIndex: Zero-based offset to the value to be set
	LONG,  # dwNewLong: The replacement value
)


SetLayeredWindowAttributes = WINFUNCTYPE(None)(("SetLayeredWindowAttributes", dll))
"""
Sets the opacity and transparency color key of a layered window.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setlayeredwindowattributes
"""
SetLayeredWindowAttributes.restype = BOOL
SetLayeredWindowAttributes.argtypes = (
	HWND,  # hwnd: Handle to the layered window
	COLORREF,  # crKey: the transparency color key to be used when composing the layered window
	BYTE,  # bAlpha: Alpha value used to describe the opacity of the layered window
	DWORD,  # dwFlags: An action to be taken
)


RedrawWindow = WINFUNCTYPE(None)(("RedrawWindow", dll))
"""
Updates the specified rectangle or region in a window's client area.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-redrawwindow
"""
RedrawWindow.restype = BOOL
RedrawWindow.argtypes = (
	HWND,  # hWnd: Handle to the window to be redrawn
	PRECT,  # lprcUpdate: The coordinates, in device units, of the update rectangle
	HRGN,  # hrgnUpdate: Handle to the update region
	UINT,  # flags: One or more redraw flags
)


FindWindow = WINFUNCTYPE(None)(("FindWindowW", dll))
"""
Retrieves a handle to the top-level window whose class name and window name match the specified strings.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-findwindoww
"""
FindWindow.restype = HWND
FindWindow.argtypes = (
	LPCWSTR,  # lpClassName: The class name or a class atom
	LPCWSTR,  # lpWindowName: The window name (title)
)

MessageBox = WINFUNCTYPE(None)(("MessageBoxW", dll))
"""
Displays a modal dialog box.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messageboxw
"""
MessageBox.restype = c_int
MessageBox.argtypes = (
	HWND,  # hWnd: Optional handle to the owner window of the message box
	LPCWSTR,  # lpText: The message to be displayed
	LPCWSTR,  # lpCaption: The dialog box title
	UINT,  # uType: The contents and behavior of the dialog box
)

ScreenToClient = WINFUNCTYPE(None)(("ScreenToClient", dll))
"""
Converts the screen coordinates of a specified point on the screen to client-area coordinates.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-screentoclient
"""
ScreenToClient.restype = BOOL
ScreenToClient.argtypes = (
	HWND,  # hWnd: handle to the window whose client area will be used for the conversion
	LPPOINT,  # lpPoint: the screen coordinates to be converted
)

ClientToScreen = WINFUNCTYPE(None)(("ClientToScreen", dll))
"""
converts the client-area coordinates of a specified point to screen coordinates.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-clienttoscreen
"""
ClientToScreen.restype = BOOL
ClientToScreen.argtypes = (
	HWND,  # hWnd: Handle to the window whose client area is used for the conversion
	LPPOINT,  # lpPoint: The client coordinates to be converted
)

WindowFromPoint = WINFUNCTYPE(None)(("WindowFromPoint", dll))
"""
Retrieves a handle to the window that contains the specified point.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-windowfrompoint
"""
WindowFromPoint.restype = HWND
WindowFromPoint.argtypes = (
	POINT,  # Point: The point to be checked
)

AttachThreadInput = WINFUNCTYPE(None)(("AttachThreadInput", dll))
"""
Attaches or detaches the input processing mechanism of one thread to that of another thread.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-AttachThreadInput
"""
AttachThreadInput.restype = BOOL
AttachThreadInput.argtypes = (
	DWORD,  # idAttach: The identifier of the thread to be attached to another thread
	DWORD,  # idAttachTo: The identifier of the thread to which idAttach will be attached
	BOOL,  # fAttach: If TRUE, the threads are attached; otherwise, they are detached
)

MapVirtualKeyEx = WINFUNCTYPE(None)(("MapVirtualKeyExW", dll))
"""
Translates a virtual-key code or scan code  into a scan code, character value or virtual-key code.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-MapVirtualKeyExW
"""
MapVirtualKeyEx.restype = UINT
MapVirtualKeyEx.argtypes = (
	UINT,  # uCode: The virtual key code or scan code for a key
	UINT,  # uMapType: The translation to perform
	HKL,  # dwhkl: Input locale identifier to use for translating the specified code
)

MsgWaitForMultipleObjects = WINFUNCTYPE(None)(("MsgWaitForMultipleObjects", dll))
"""
Waits until one or all of the specified objects are in the signaled state or the time-out interval elapses.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-msgwaitformultipleobjects
"""
MsgWaitForMultipleObjects.restype = DWORD
MsgWaitForMultipleObjects.argtypes = (
	DWORD,  # nCount: The number of object handles in the array pointed to by pHandles
	PHANDLE,  # pHandles: An array of object handles
	BOOL,  # fWaitAll: Whether to wait for all handles to be signaled
	DWORD,  # dwMilliseconds: The time-out interval, in milliseconds
	DWORD,  # dwWakeMask: The input types for which an input event object handle will be added to the array of object handles
)

ShowWindow = WINFUNCTYPE(None)(("ShowWindow", dll))
"""
Sets the specified window's show state.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow
"""
ShowWindow.restype = BOOL
ShowWindow.argtypes = (
	HWND,  # hWnd: Handle to the window
	c_int,  # nCmdShow: Controls how the window is to be shown
)

SetWindowPos = WINFUNCTYPE(None)(("SetWindowPos", dll))
"""
Changes the size, position, and Z order of a child, pop-up, or top-level window.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-SetWindowPos
"""
SetWindowPos.restype = BOOL
SetWindowPos.argtypes = (
	HWND,  # hWnd:Handle to the window
	HWND,  # hWndInsertAfter: Optional handle to the window to precede the positioned window in the Z order
	c_int,  # X: The new position of the left side of the window, in client coordinates
	c_int,  # Y: The new position of the top of the window, in client coordinates
	c_int,  # cx: The new width of the window, in pixels
	c_int,  # cy: The new height of the window, in pixels
	UINT,  # uFlags: The window sizing and positioning flags
)

UpdateWindow = WINFUNCTYPE(None)(("UpdateWindow", dll))
"""
Updates the client area of the specified window by sending a WM_PAINT message to the window if the window's update region is not empty.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-UpdateWindow
"""
UpdateWindow.restype = BOOL
UpdateWindow.argtypes = (
	HWND,  # hWnd: Handle to the window to be updated
)

PostQuitMessage = WINFUNCTYPE(None)(("PostQuitMessage", dll))
"""
Indicates to the system that a thread has made a request to terminate.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-postquitmessage
"""
PostQuitMessage.restype = None
PostQuitMessage.argtypes = (
	c_int,  # nExitCode: The application exit code
)

InvalidateRect = WINFUNCTYPE(None)(("InvalidateRect", dll))
"""
Adds a rectangle to the specified window's update region.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-invalidaterect
"""
InvalidateRect.restype = BOOL
InvalidateRect.argtypes = (
	HWND,  # hWnd: Handle to the window whose update region has changed
	PRECT,  # lpRect: the client coordinates of the rectangle to be added to the update region
	BOOL,  # bErase: whether to erased the background when processing the update region
)

PostThreadMessage = WINFUNCTYPE(None)(("PostThreadMessageW", dll))
"""
Posts a message to the message queue of the specified thread.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-postthreadmessagew
"""
PostThreadMessage.restype = BOOL
PostThreadMessage.argtypes = (
	DWORD,  # idThread: The identifier of the thread to which the message is to be posted
	UINT,  # Msg: The type of message to be posted
	WPARAM,  # wParam: Additional message-specific information
	LPARAM,  # lParam: Additional message-specific information
)

ToUnicodeEx = WINFUNCTYPE(None)(("ToUnicodeEx", dll))
"""
Translates the specified virtual-key code and keyboard state to the corresponding Unicode character or characters.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-tounicodeex
"""
ToUnicodeEx.restype = int
ToUnicodeEx.argtypes = (
	UINT,  # wVirtKey: The virtual-key code to be translated
	UINT,  # wScanCode: The hardware scan code of the key to be translated
	PBYTE,  # lpKeyState: a 256-byte array that contains the current keyboard state
	LPWSTR,  # pwszBuff: The buffer that receives the translated character(s) as UTF-16 code units
	c_int,  # cchBuff: The size, in characters, of pwszBuff
	UINT,  # wFlags: The behavior of the function
	HKL,  # dwhkl: The input locale identifier used to translate the specified code
)

SendMessageTimeout = WINFUNCTYPE(None)(("SendMessageTimeoutW", dll))
"""
Sends the specified message to one or more windows.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendmessagetimeoutw
"""
SendMessageTimeout.restype = LRESULT
SendMessageTimeout.argtypes = (
	HWND,  # hWnd: Handle to the window whose window procedure will receive the message
	UINT,  # Msg: The message to be sent
	WPARAM,  # wParam: Any additional message-specific information
	LPARAM,  # lParam: Any additional message-specific information
	UINT,  # fuFlags: The behavior of this function
	UINT,  # uTimeout: The duration of the time-out period, in milliseconds
	PDWORD_PTR,  # lpdwResult: The result of the message processing
)

GetThreadDesktop = WINFUNCTYPE(None)(("GetThreadDesktop", dll))
"""
Retrieves a handle to the desktop assigned to the specified thread.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getthreaddesktop
"""
GetThreadDesktop.restype = HDESK
GetThreadDesktop.argtypes = (
	DWORD,  # dwThreadId: The thread identifier
)

GetUserObjectInformation = WINFUNCTYPE(None)(("GetUserObjectInformationW", dll))
"""
Retrieves information about the specified window station or desktop object.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getuserobjectinformationw
"""
GetUserObjectInformation.restype = BOOL
GetUserObjectInformation.argtypes = (
	HANDLE,  # hObj: Handle to the window station or desktop object
	c_int,  # nIndex: The information to be retrieved
	c_void_p,  # pvInfo: Buffer to receive the object information
	DWORD,  # nLength: Size of pvInfo, in bytes
	LPDWORD,  # lpnLengthNeeded: receives the number of bytes required to store the requested information
)

POINTER_INPUT_TYPE = DWORD

RegisterPointerInputTarget = WINFUNCTYPE(None)(("RegisterPointerInputTarget", dll))
"""
Allows the caller to register a target window to which all pointer input of the specified type is redirected.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerpointerinputtarget
"""
RegisterPointerInputTarget.restype = BOOL
RegisterPointerInputTarget.argtypes = (
	HWND,  # hwnd: The window to register as a global redirection target.
	POINTER_INPUT_TYPE,  # pointerType: Type of pointer input to be redirected to the specified window
)

UnregisterPointerInputTarget = WINFUNCTYPE(None)(("UnregisterPointerInputTarget", dll))
"""
Allows the caller to unregister a target window to which all pointer input of the specified type is redirected.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-unregisterpointerinputtarget
"""
UnregisterPointerInputTarget.restype = BOOL
UnregisterPointerInputTarget.argtypes = (
	HWND,  # hwnd: Window to be un-registered as a global redirection target on its desktop
	POINTER_INPUT_TYPE,  # pointerType: Type of pointer input to no longer be redirected to the specified window
)

DestroyWindow = WINFUNCTYPE(None)(("DestroyWindow", dll))
"""
Destroys the specified window.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-destroywindow
"""
DestroyWindow.restype = BOOL
DestroyWindow.argtypes = (
	HWND,  # hWnd: Handle to the window to be destroyed
)

EnumChildWindows = WINFUNCTYPE(None)(("EnumChildWindows", dll))
"""
Enumerates the specified window's child windows  by sequentially passing their handles to the given callback.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-EnumChildWindows
"""
EnumChildWindows.restype = BOOL
EnumChildWindows.argtypes = (
	HWND,  # hWndParent: Handle to the parent window whose child windows are to be enumerated
	WNDENUMPROC,  # lpEnumFunc: Pointer to an application-defined callback function
	LPARAM,  # lParam: Application-defined value to be passed to the callback function
)

UnhookWindowsHookEx = WINFUNCTYPE(None)(("UnhookWindowsHookEx", dll))
"""
Removes a hook procedure installed in a hook chain by the ``SetWindowsHookEx`` function.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-UnhookWindowsHookEx
"""
UnhookWindowsHookEx.restype = BOOL
UnhookWindowsHookEx.argtypes = (
	HHOOK,  # hhk: Handle to the hook to be removed
)
DPI_AWARENESS_CONTEXT = HANDLE

SetProcessDpiAwarenessContext = WINFUNCTYPE(None)(("SetProcessDpiAwarenessContext", dll))
"""
Sets the current process to a specified dots per inch (dpi) awareness context.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setprocessdpiawarenesscontext
"""
SetProcessDpiAwarenessContext.restype = BOOL
SetProcessDpiAwarenessContext.argtypes = (
	DPI_AWARENESS_CONTEXT,  # value: A DPI_AWARENESS_CONTEXT handle to set
)

SetProcessDPIAware = WINFUNCTYPE(None)(("SetProcessDPIAware", dll))
"""
Sets the process-default DPI awareness to system-DPI awareness.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setprocessdpiaware
"""
SetProcessDPIAware.restype = BOOL
SetProcessDPIAware.argtypes = ()

EmptyClipboard = WINFUNCTYPE(None)(("EmptyClipboard", dll))
"""
Empties the clipboard, frees handles to its data, and assigns clipboard ownership to the window with it open.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-EmptyClipboard
"""
EmptyClipboard.restype = BOOL
EmptyClipboard.argtypes = ()

MapVirtualKey = WINFUNCTYPE(None)(("MapVirtualKeyW", dll))
"""
Translates a virtual-key code or scan code  into a scan code, character value or virtual-key code.

.. seealso::
	https://learn.microsoft.com/windows/win32/api/winuser/nf-winuser-mapvirtualkeyw
"""
MapVirtualKey.restype = UINT
MapVirtualKey.argtypes = (
	UINT,  # uCode: The virtual key code or scan code for a key
	UINT,  # uMapType: The translation to be performed
)

RegisterWindowMessage = WINFUNCTYPE(None)(("RegisterWindowMessageW", dll))
"""
Defines a new window message that is guaranteed to be unique throughout the system.

.. seealso::
	https://learn.microsoft.com/en-gb/windows/win32/api/winuser/nf-winuser-registerwindowmessagew
"""
RegisterWindowMessage.restype = UINT
RegisterWindowMessage.argtypes = (
	LPCWSTR,  # lpString: The message to be registered
)

ACCESS_MASK = DWORD

OpenInputDesktop = WINFUNCTYPE(None)(("OpenInputDesktop", dll))
"""
Opens the desktop that receives user input.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-openinputdesktop
"""
OpenInputDesktop.restype = HDESK
OpenInputDesktop.argtypes = (
	DWORD,  # dwFlags: Behaviour flags
	BOOL,  # fInherit: If TRUE, processes created by this process will inherit the handle
	ACCESS_MASK,  # dwDesiredAccess:
)

CloseDesktop = WINFUNCTYPE(None)(("CloseDesktop", dll))
"""
Closes an open handle to a desktop object.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-closedesktop
"""
CloseDesktop.restype = BOOL
CloseDesktop.argtypes = (
	HDESK,  # hDesktop: Handle to the desktop to be closed
)

GetKeyboardLayoutName = WINFUNCTYPE(None)(("GetKeyboardLayoutNameW", dll))
"""
Retrieves the name of the active input locale identifier (formerly called the keyboard layout) for the calling thread.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getkeyboardlayoutnamew
"""
GetKeyboardLayoutName.restype = BOOL
GetKeyboardLayoutName.argtypes = (
	LPWSTR,  # pwszKLID: The buffer that receives the name of the input locale identifier, including the terminating null character
)

GetDC = WINFUNCTYPE(None)(("GetDC", dll))
"""
Retrieves a handle to a device context for the client area of a specified window or the entire screen.

.. seealso::
https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc
"""
GetDC.restype = HDC
GetDC.argtypes = (
	HWND,  # hWnd: Handle to the window whose DC is to be retrieved, or NULL to retrieve the DC for the entire screen
)

ReleaseDC = WINFUNCTYPE(None)(("ReleaseDC", dll))
"""
Releases a device context, freeing it for use by other applications.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-releasedc
"""
ReleaseDC.restype = int
ReleaseDC.argtypes = (
	HWND,  # hWnd: Handle to the window whose DC is to be released
	HDC,  # hDC: Handle to the DC to be released
)

GetWindowRect = WINFUNCTYPE(None)(("GetWindowRect", dll))
"""
Retrieves the dimensions of the bounding rectangle of the specified window.

..  seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowrect
"""
GetWindowRect.restype = BOOL
GetWindowRect.argtypes = (
	HWND,  # hWnd: Handle to the window
	LPRECT,  # lpRect: RECT that receives the screen coordinates of the upper-left and lower-right corners of the window
)
IsWindowUnicode = WINFUNCTYPE(None)(("IsWindowUnicode", dll))
"""
Determines whether the specified window is a native Unicode window.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-iswindowunicode
"""
IsWindowUnicode.restype = BOOL
IsWindowUnicode.argtypes = (
	HWND,  # hWnd: Handle to the window to be tested
)

try:
	_GhostWindowFromHungWindow = dll.GhostWindowFromHungWindow
	"""
	Retrieves a handle to a window which is ghosting a hung window.

	.. warning::
		This is an undocumented part of the Windows API!

	.. seealso::
		https://undoc.airesoft.co.uk/user32.dll/GhostWindowFromHungWindow.php
		https://ntdoc.m417z.com/ghostwindowfromhungwindow
	"""
except AttributeError:
	_GhostWindowFromHungWindow = None
else:
	_GhostWindowFromHungWindow.restype = HWND
	_GhostWindowFromHungWindow.argtypes = (
		HWND,  # hwndHung: Handle of a hung window
	)

GetSysColor = WINFUNCTYPE(None)(("GetSysColor", dll))
"""
Retrieves the current color of the specified display element.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsyscolor
"""
GetSysColor.restype = DWORD
GetSysColor.argtypes = (
	c_int,  # nIndex: The display element whose color is to be retrieved
)

WindowFromPhysicalPoint = WINFUNCTYPE(None)(("WindowFromPhysicalPoint", dll))
"""
Retrieves a handle to the window that contains the specified physical point.

... seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-windowfromphysicalpoint
"""
WindowFromPhysicalPoint.restype = HWND
WindowFromPhysicalPoint.argtypes = (
	POINT,  # Point
)

LogicalToPhysicalPointForPerMonitorDPI = WINFUNCTYPE(None)(("LogicalToPhysicalPointForPerMonitorDPI", dll))
"""
Converts a point in a window from logical to physical coordinates, regardless of the dpi awareness of the caller.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-logicaltophysicalpointforpermonitordpi
"""
LogicalToPhysicalPointForPerMonitorDPI.restype = BOOL
LogicalToPhysicalPointForPerMonitorDPI.argtypes = (
	HWND,  # hWnd: Handle to the window whose transform is used for the conversion
	LPPOINT,  # lpPoint: The logical coordinates to be converted in place
)

PhysicalToLogicalPointForPerMonitorDPI = WINFUNCTYPE(None)(("PhysicalToLogicalPointForPerMonitorDPI", dll))
"""
Converts a point in a window from physical to logical coordinates, regardless of the dpi awareness of the caller.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-physicaltologicalpointforpermonitordpi
"""
PhysicalToLogicalPointForPerMonitorDPI.restype = BOOL
PhysicalToLogicalPointForPerMonitorDPI.argtypes = (
	HWND,  # hWnd: Handle to the window whose transform is used for the conversion
	LPPOINT,  # lpPoint: The physical/screen coordinates to be converted in-place
)

GetDpiForWindow = WINFUNCTYPE(None)(("GetDpiForWindow", dll))
"""
Returns the dots per inch (dpi) value for the specified window.

.. seealso::
	https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdpiforwindow
"""
GetDpiForWindow.restype = UINT
GetDpiForWindow.argtypes = (
	HWND,  # hwnd: The window that you want to get information about
)
